package com.bx.implatform.portal.service.Impl;


import com.alibaba.fastjson.JSON;
import com.bx.imcommon.enums.IMTerminalType;
import com.bx.imcommon.util.JwtUtil;
import com.bx.implatform.config.props.JwtProperties;
import com.bx.implatform.entity.PubUser;
import com.bx.implatform.entity.User;
import com.bx.implatform.exception.GlobalException;
import com.bx.implatform.mapper.PubUserMapper;
import com.bx.implatform.portal.config.PortalProperties;
import com.bx.implatform.portal.entity.DelTodoEntity;
import com.bx.implatform.portal.entity.MessageEntity;
import com.bx.implatform.portal.entity.TodoEntity;
import com.bx.implatform.portal.entity.UpTodoEntity;
import com.bx.implatform.portal.service.PortalApiService;
import com.bx.implatform.portal.utils.PortalExternalApiService;
import com.bx.implatform.service.UserService;
import com.bx.implatform.session.SessionContext;
import com.bx.implatform.session.UserSession;
import com.bx.implatform.util.BeanUtils;
import com.bx.implatform.util.ConvertNumbers;
import com.bx.implatform.vo.LoginVO;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class PortalApiServiceImpl implements PortalApiService {

    @Resource
    private PortalExternalApiService externalApiService;
    @Resource
    private PortalProperties portalProperties;
    @Resource
    private PubUserMapper pubUserMapper;
    @Resource
    private UserService userService;
    @Resource
    private JwtProperties jwtProperties;


    /**
     * 获取accessToken
     *
     * @param userId
     * @return
     */
    @Override
    public LoginVO getAccessToken(String userId, Integer terminal) {
        try {
            // 获取门户AccessToken
            // String url = buildUrl("/v1/oauth2/getAccessToken");
            // log.debug("请求门户Token: {}", url);
            // long startTime = System.currentTimeMillis();
            // // 构建参数
            // JsonNode payload = mapper.createObjectNode()
            //         .put("appKey", portalProperties.getAppKey())
            //         .put("appSecret", portalProperties.getAppSecret());
            // String response = externalApiService.post(url, payload, String.class);
            // log.debug("请求门户token接口响应耗时: {}ms, 响应数据: {}",
            //         System.currentTimeMillis() - startTime,
            //         StringUtils.substring(response, 0, 200));
            // JsonNode json = mapper.readTree(response);
            // PortalResultAccessToken resultToken = parseResponse(json, PortalResultAccessToken.class);
            // if (resultToken == null) {
            //     throw new GlobalException("获取门户token失败");
            // }
            // if (StringUtils.isBlank(resultToken.getAccessToken())) {
            //     log.error("获取门户token失败: {}", json.get("data").toPrettyString());
            //     throw new GlobalException("获取门户token失败");
            // }
            // log.info("获取门户token: access_token={}, expires_in={}", resultToken.getAccessToken(), resultToken.getExpiresIn());
            //
            // // 获取用户信息，生成业务系统token
            // String path = buildUrl("/v1/user/getUserInfo");
            // log.debug("获取用户信息: {}", url);
            // long startTimeUserInfo = System.currentTimeMillis();
            // // 构建参数
            // JsonNode paramMap = mapper.createObjectNode()
            //         .put("accessToken", resultToken.getAccessToken())
            //         .put("code", code);
            // String resUserInfo = externalApiService.post(path, paramMap, String.class);
            // log.debug("请求门户token接口响应耗时: {}ms, 响应数据: {}",
            //         System.currentTimeMillis() - startTimeUserInfo,
            //         StringUtils.substring(response, 0, 200));
            // JsonNode userJson = mapper.readTree(resUserInfo);
            // PortalResultUser resultUser = parseResponse(userJson, PortalResultUser.class);
            // if (resultUser == null) {
            //     throw new GlobalException("获取门户用户信息失败");
            // }
            User user = userService.findUserByUserName(userId);
            if (user == null) {
                throw new GlobalException("系统用户和门户用户不同步，请联系管理员");
            }
            return generateLoginToken(user,terminal == null ? IMTerminalType.APP.code() : IMTerminalType.LARGE_PC.code());
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("生成token失败: {}", e.getMessage(), e);
            throw new GlobalException("生成token失败");
        }
    }

    /**
     * 发送工作通知
     *
     * @param msg
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public JsonNode sendMsg(MessageEntity msg) {
        try {
            String url = buildUrl("/v1/message/send");
            log.debug("请求发送工作通知接口: {}", url);
            JsonNode response = externalApiService.post(url, msg, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("发送工作通知数据解析失败: {}", e.getMessage(), e);
            throw new GlobalException("发送工作通知数据解析失败");
        }
    }

    /**
     * 获取门户部门列表
     *
     * @return 部门列表
     * @throws RuntimeException 当接口调用失败时抛出
     */
    @Override
    public JsonNode deptList(@NotNull String deptId) {
        try {
            String url = buildUrl("/v1/dept/list?deptId=" + deptId);
            log.debug("准备调用部门列表接口，URL: {}", url);
            JsonNode response = externalApiService.get(url, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("调用部门列表接口失败: {}", e.getMessage(), e);
            throw new GlobalException("获取部门信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取部门详情
     *
     * @return 部门详情
     * @throws RuntimeException 当接口调用失败时抛出
     */
    @Override
    public JsonNode deptDetail(@NotNull String deptId) {
        try {
            String url = buildUrl("/v1/dept/getDeptDetail?deptId=" + deptId);
            log.debug("请求部门详情接口: {}", url);
            JsonNode response = externalApiService.get(url, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取部门详情异常: {}", e.getMessage(), e);
            throw new GlobalException("获取部门详情失败");
        }
    }

    /**
     * 获取用户列表
     *
     * @param deptId
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public JsonNode userList(@NotNull String deptId, Long pageNum, Long pageSize) {
        try {
            String url = buildUrl("/v1/user/listByDeptId?deptId="
                    + deptId + "&pageSize=" + pageSize + "&pageNum=" + pageNum);
            log.debug("准备调用用户列表接口，URL: {}", url);
            JsonNode response = externalApiService.get(url, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("调用用户列表接口失败: {}", e.getMessage(), e);
            throw new GlobalException("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户详情
     *
     * @return
     */
    @Override
    public JsonNode userDetail(@NotNull String userId) {
        try {
            String url = buildUrl("/v1/user/detail?userId=" + userId);
            log.debug("请求用户详情接口: {}", url);
            JsonNode response = externalApiService.get(url, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取用户详情异常: {}", e.getMessage(), e);
            throw new GlobalException("获取用户详情失败");
        }
    }

    /**
     * 创建待办/待阅
     *
     * @param todo
     * @return
     */
    @Override
    public JsonNode createTodo(TodoEntity todo) {
        try {
            String url = buildUrl("/v1/todo/create");
            log.debug("请求创建待办/待阅接口: {}", url);
            JsonNode response = externalApiService.post(url, todo, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("创建待办/待阅数据解析失败: {}", e.getMessage(), e);
            throw new GlobalException("创建待办/待阅数据解析失败");
        }
    }

    /**
     * 更新待办/待阅
     *
     * @param todo
     * @return
     */
    @Override
    public JsonNode updateTodo(UpTodoEntity todo) {
        try {
            String url = buildUrl("/v1/todo/update");
            log.debug("请求更新待办/待阅接口: {}", url);
            JsonNode response = externalApiService.post(url, todo, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新待办/待阅数据解析失败: {}", e.getMessage(), e);
            throw new GlobalException("更新待办/待阅数据解析失败");
        }
    }

    /**
     * 删除待办/待阅
     *
     * @param todo
     * @return
     */
    @Override
    public JsonNode deleteTodo(DelTodoEntity todo) {
        try {
            String url = buildUrl("/v1/todo/delete");
            log.debug("请求删除待办/待阅接口: {}", url);
            JsonNode response = externalApiService.post(url, todo, JsonNode.class);
            return ConvertNumbers.convertNumbersToString(response);
        } catch (GlobalException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除待办/待阅数据解析失败: {}", e.getMessage(), e);
            throw new GlobalException("删除待办/待阅数据解析失败:" + e.getMessage());
        }
    }


    private PubUser getCurrentUser() {
        UserSession session = SessionContext.getSession();
        if (session == null || StringUtils.isBlank(session.getUserName())) {
            throw new GlobalException("用户会话不存在或已过期");
        }

        PubUser pubUser = pubUserMapper.selectById(session.getUserName());
        if (pubUser == null || StringUtils.isBlank(pubUser.getOrganId())) {
            throw new GlobalException("用户组织信息不完整");
        }
        return pubUser;
    }

    private String buildUrl(String path) {
        return portalProperties.getUrl() + path;
    }


    private LoginVO generateLoginToken(User user,Integer terminal) {
        UserSession session = BeanUtils.copyProperties(user, UserSession.class);
        session.setUserId(user.getId());
        session.setTerminal(terminal);

        String strJson = JSON.toJSONString(session);
        String accessToken = JwtUtil.sign(user.getId(), strJson, jwtProperties.getAccessTokenExpireIn(), jwtProperties.getAccessTokenSecret());
        String refreshToken = JwtUtil.sign(user.getId(), strJson, jwtProperties.getRefreshTokenExpireIn(), jwtProperties.getRefreshTokenSecret());

        LoginVO vo = new LoginVO();
        vo.setAccessToken(accessToken);
        vo.setAccessTokenExpiresIn(jwtProperties.getAccessTokenExpireIn());
        vo.setRefreshToken(refreshToken);
        vo.setRefreshTokenExpiresIn(jwtProperties.getRefreshTokenExpireIn());
        return vo;
    }
}
